package com.devshephard.rpcframework.servletsync.service.impl;


import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;

import javax.servlet.AsyncContext;
import javax.servlet.AsyncEvent;
import javax.servlet.AsyncListener;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Date;

@Component
@Configuration
@Slf4j
public class SimpleSyncServletImpl {

    public SimpleSyncServletImpl() {
    }

    public void execute(HttpServletRequest request, HttpServletResponse response) {
        System.out.println(Thread.currentThread().getName() + " 执行execute方法");
    }

    public void executeChain(HttpServletRequest request, HttpServletResponse response,
                             String result,Object obj,String methodName) throws InterruptedException {



        AsyncContext asyncContext = request.startAsync();

        asyncContext.addListener(new AsyncListener() {

            @Override
            public void onComplete(AsyncEvent asyncEvent) throws IOException {
                new Thread(()->{
                    //afterExecute();
                    System.out.println(obj.hashCode());
                    Method[] methods = obj.getClass().getMethods();
                    for (Method method : methods) {
                        if(method.getName().equals(methodName)){
                            try {
                                method.invoke(obj);
                            } catch (IllegalAccessException e) {
                                e.printStackTrace();
                            } catch (InvocationTargetException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }).start();
            }
            @Override
            public void onTimeout(AsyncEvent asyncEvent) throws IOException {
                log.info(new Date() + Thread.currentThread().getName() +"response线程处理超时");
            }
            @Override
            public void onError(AsyncEvent asyncEvent) throws IOException {
                log.info(new Date() + Thread.currentThread().getName() +"response线程处理异常");
            }
            @Override
            public void onStartAsync(AsyncEvent asyncEvent) throws IOException {
                log.info(new Date() + Thread.currentThread().getName() +"response线程开始处理事件");
            }
        });


        /**
         * 可以使用下面的方式,也可以執行異步servlet
         */
       /* Runnable runnable = () -> {
            try {
                this.execute(request,response);
                asyncContext.getResponse().getWriter().write(result);
            } catch (IOException e) {
                e.printStackTrace();
            }

            asyncContext.complete();

        };

        asyncContext.start(runnable);*/

        Runnable runnable = () -> {
            try {
                this.execute(request,response);
                asyncContext.getResponse().getWriter().write(result);
            } catch (IOException e) {
                e.printStackTrace();
            }

            asyncContext.complete();

        };

        new Thread(runnable).start();





    }




}
